/**
 * @author Tobias Boehm
 *
 * 09.05.2011
 */
package org.anddev.andengine.extension.tbsengine.server;

import org.anddev.andengine.extension.tbsengine.server.AbsGameServer.GameServerState;
import org.anddev.andengine.extension.tbsengine.shared.MatchJoinOrPreparationType;
import org.anddev.andengine.extension.tbsengine.shared.NoMatchPreparationTypeProvidedException;
import org.anddev.andengine.extension.tbsengine.shared.TBSengineConstants;

import android.app.Service;
import android.content.Intent;

/**
 * This is an abstract implementation of a {@link Service} which contains and 
 * manages an instance of your implementation of {@link AbsGameServer}.
 * You may use this class to implement your own game server service.
 * 
 * @author Tobias Boehm
 *
 * @param <GameServerClass> - Your implementation of {@link AbsGameServer}.
 */
public abstract class AbsGameServerService<GameServerClass extends AbsGameServer> extends Service {

	/**
	 * A reference to the game server which is managed by this service.
	 */
	protected GameServerClass mGameServer;
	

	/**
	 * This method should return an instance of your implementation of {@link AbsGameServer}.
	 * You may determine the type of the game server on the basis of the {@link MatchJoinOrPreparationType} parameter.
	 *  
	 * @param matchPreparationType
	 * 
	 * @return - An instance of your implementation of {@link AbsGameServer}.
	 */
	protected abstract GameServerClass createGameServer(final MatchJoinOrPreparationType matchPreparationType);
	
	/**
	 * If the service is destroyed, it tries to stop the game server first.
	 */
	@Override
	public void onDestroy() {
		
		if(this.mGameServer != null){

			this.mGameServer.stopServer();
		}
		
		super.onDestroy();
	}
	
	/**
	 * This method handles start service commands. You should provide the name 
	 * of a {@link MatchJoinOrPreparationType} as Intent "action".
	 * Otherwise the service will not start.
	 */
	@Override
	public int onStartCommand(Intent pIntent, int flags, int startId) {
		
		final MatchJoinOrPreparationType matchPreparationType;
		
		try {
			
			matchPreparationType = MatchJoinOrPreparationType.valueOf(pIntent.getStringExtra(TBSengineConstants.TBSE_MATCH_JOIN_OR_PREPARATION_TYPE_INTENT_EXTRA));
						
		} catch (Exception e) {
			
			this.stopSelf();
			
			throw new NoMatchPreparationTypeProvidedException();			
		}
		
		/*
		 *  If there is no game server the following code
		 *  will create and start a new one. If there is a game server but
		 *  the server is DOWN for any reason it will restart the
		 *  game server.
		 */
		if(this.mGameServer == null){
		
			this.mGameServer = this.createGameServer(matchPreparationType);
			
			this.mGameServer.startServer();
		
		}else if(this.mGameServer.getGameServerState() != GameServerState.RUNNING){
			
			this.mGameServer.startServer();
		}
			
		return START_STICKY;		
	}
}
